home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
Better AD security
/
Source
/
InstallCode.c
< prev
next >
Wrap
Text File
|
1996-06-21
|
13KB
|
555 lines
/* NAME:
InstallCode.c
WRITTEN BY:
Dair Grant
DESCRIPTION:
Routines for installing various code resources.
___________________________________________________________________________
*/
//=============================================================================
// Include files
//-----------------------------------------------------------------------------
#include <Memory.h>
#include <Gestalt.h>
#include <Errors.h>
#include <Resources.h>
#include <Shutdown.h>
#include <Timer.h>
#include "ES.h"
#include "ES Address Table.h"
#include "InstallCode.h"
//=============================================================================
// Private function prototypes
//-----------------------------------------------------------------------------
OSErr InstallTrapPatch(short i, Ptr theCode);
OSErr InstallGestaltSelector(short i, Ptr theCode);
OSErr InstallShutdownTask(short i, Ptr theCode);
OSErr InstallVBLTask(short i, Ptr theCode);
OSErr InstallLowMemFilter(short i, Ptr theCode);
OSErr InstallCodeBlock(short i, Ptr theCode);
OSErr InstallTimeManagerTask(short i, Ptr theCode);
//=============================================================================
// Global variables
//-----------------------------------------------------------------------------
extern ESParamBlock gTheParamBlock;
extern ESAddressTable *gTheESAddressTable;
//=============================================================================
// InstallCode : Install a code resource depending on its type.
//-----------------------------------------------------------------------------
// Note : We get the index of something in gTheParamBlock.theCodeResources
// and case out on its type to do the installation. If any error
// occurs, we return the error code - our caller fills in the
// details in gTheParamBlock.
//-----------------------------------------------------------------------------
OSErr InstallCode(short i)
{ Handle theHnd;
OSErr theErr;
Ptr theCode;
// Get the code resource we're after, and return if it wasn't there.
theHnd = Get1Resource(gTheParamBlock.theCodeResources[i].resType,
gTheParamBlock.theCodeResources[i].resID);
if (theHnd == nil)
return(resNotFound);
// Unlock the resource, compact the heap, then lock it down. We then
// detach it so it stays around after Extension Shell is gone.
HUnlock(theHnd);
ResrvMem(GetHandleSize(theHnd));
HLock(theHnd);
DetachResource(theHnd);
// Get a clean address from the handle
theCode = (Ptr) StripAddress(*theHnd);
// Now case out on the type of the code, and call the install routine
switch(gTheParamBlock.theCodeResources[i].codeType) {
case kTrapPatchType:
theErr = InstallTrapPatch(i, theCode);
break;
case kGestaltSelectorType:
theErr = InstallGestaltSelector(i, theCode);
break;
case kShutdownTaskType:
theErr = InstallShutdownTask(i, theCode);
break;
case kVBLTaskType:
theErr = InstallVBLTask(i, theCode);
break;
case kLowMemFilterType:
theErr = InstallLowMemFilter(i, theCode);
break;
case kCodeBlockType:
theErr = InstallCodeBlock(i, theCode);
break;
case kTimeManagerTaskType:
theErr = InstallTimeManagerTask(i, theCode);
break;
default:
theErr = noErr;
}
// Return any errors that occurred
return(theErr);
}
//=============================================================================
// InstallESAddressTable : Install an address table.
//-----------------------------------------------------------------------------
// Note : We install the Gestalt selector, call Gestalt to obtain the
// address of the address table, and leave the result in
// gTheESAddressTable.
//
// Because the address table is so fundamental, any failure
// to load, install, or call it drops us into MacsBug.
//
// We also initialse the magicNumber and versionNumber fields.
//-----------------------------------------------------------------------------
void InstallESAddressTable(void)
{ Handle theHnd;
OSErr theErr;
ProcPtr theCode;
// Load the AddressTable Gestalt selector, and install it with NewGestalt.
theHnd = GetResource(kAddrsTableCodeType, kAddrsTableCodeID);
if (theHnd == nil)
DebugStr("\pExtension Shell - couldn't find Address Table resource");
// We have it, so lock it in place
HUnlock(theHnd);
ResrvMem(GetHandleSize(theHnd));
HLock(theHnd);
DetachResource(theHnd);
// Get a clean address from the handle
theCode = (ProcPtr) StripAddress(*theHnd);
// Install the address table as a Gestalt selector
theErr = NewGestalt(gTheParamBlock.addressTableSelector,
NewSelectorFunctionProc(theCode));
if (theErr != noErr)
DebugStr("\pExtension Shell - couldn't install AddressTable");
// Call Gestalt to get the address of the address table and initialise
// the magicNumber and versionNumber fields.
theErr = Gestalt(gTheParamBlock.addressTableSelector, (long *) &gTheESAddressTable);
if (theErr != noErr)
DebugStr("\pExtension Shell - couldn't call AddressTable");
else
{
gTheESAddressTable->magicNumber = 0xDEADBEEF;
gTheESAddressTable->versionNumber = 0xFEEDFACE;
}
}
//=============================================================================
// InstallTrapPatch : Install a trap patch.
//-----------------------------------------------------------------------------
// Note : Given a trap word and a pointer to the new routine, we save
// the original entry in the dispatch table and insert the new
// one.
//
// We assume that the trap *is* implemented. If globalPatch is
// true, the patch is applied to all applications (this is the
// default behaviour). If globalPatch is false, the patch only
// takes affect in the application appName. (THIS FEATURE IS
// NOT IMPLEMENTED YET)
//-----------------------------------------------------------------------------
OSErr InstallTrapPatch(short i, Ptr theCode)
{ short trapWord;
TrapType trapType;
ProcPtr oldCodeAddress;
// Find out what we need to know
trapWord = gTheParamBlock.theCodeResources[i].theCodeThing.theTrapPatch.trapWord;
trapType = (trapWord & 0x0800) ? ToolTrap : OSTrap;
// Replace the old value in the dispatch table with the new value.
oldCodeAddress = (ProcPtr) StripAddress((Ptr) NGetTrapAddress(trapWord, trapType));
NSetTrapAddress((UniversalProcPtr) theCode, trapWord, trapType);
// Handle globalPatch and appName
//
// THIS FEATURE IS NOT IMPLEMENTED YET - IT WOULD NEED SOME KIND OF
// GENERIC EXTENSION SHELL PATCH TO SOMETHING LIKE _INITALLPACKS OR
// _INITGRAF, AND THEN THE APPLICATION OF PATCHES DEPENDING ON
// THE APPLICATION BEING EXECUTED.
//
//
// Fill in the entry in the address table and save the address of the new code.
gTheESAddressTable->theTable[i] = oldCodeAddress;
gTheParamBlock.theCodeResources[i].theAddress = theCode;
// Return any errors
return(noErr);
}
//=============================================================================
// InstallGestaltSelector : Install a Gestalt Selector.
//-----------------------------------------------------------------------------
OSErr InstallGestaltSelector(short i, Ptr theCode)
{ OSErr theErr;
SelectorFunctionUPP theUPP;
AGestaltSelector *theGestaltInfo;
// Find out what we need to know
theGestaltInfo = &gTheParamBlock.theCodeResources[i].theCodeThing.theGestaltSelector;
theUPP = NewSelectorFunctionProc(theCode);
// Try and install the routine
theErr = NewGestalt(theGestaltInfo->theSelector, theUPP);
// If the selector exists, replace it if we're allowed to, and save
// the address of the old routine in the address table
if (theErr == gestaltDupSelectorErr && theGestaltInfo->overwriteExistingSelector)
theErr = ReplaceGestalt(theGestaltInfo->theSelector, theUPP,
(SelectorFunctionUPP *) &gTheESAddressTable->theTable[i]);
// If there wasn't a problem, save the address of the new code. The address
// table is only used if we need to get access to the old Gestalt routine.
if (theErr == noErr)
gTheParamBlock.theCodeResources[i].theAddress = theCode;
// Return any errors
return(theErr);
}
//=============================================================================
// InstallShutdownTask : Install a Shutdown Task.
//-----------------------------------------------------------------------------
OSErr InstallShutdownTask(short i, Ptr theCode)
{
// Install the task with its flags and save the address in gTheParamBlock.
// We don't use the address table at all.
ShutDwnInstall(NewShutDwnProc(theCode),
gTheParamBlock.theCodeResources[i].theCodeThing.theShutdownTask.theFlags);
gTheParamBlock.theCodeResources[i].theAddress = theCode;
// Return any errors
return(noErr);
}
//=============================================================================
// InstallVBLTask : Install a VBL task.
//-----------------------------------------------------------------------------
OSErr InstallVBLTask(short i, Ptr theCode)
{ VBLTask *theVblPtr;
OSErr theErr;
// Allocate a little block of memory in the System Heap for the task information
theVblPtr = (VBLTask*) NewPtrSys(sizeof(VBLTask));
// Fill in the fields, and install it as a VBL task
theVblPtr->qType = vType;
theVblPtr->vblAddr = NewVBLProc(theCode);
theVblPtr->vblCount = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblCount;
theVblPtr->vblPhase = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblPhase;
theErr = VInstall((QElemPtr) theVblPtr);
// Save the address of the VBLTask structure in the address table and the param block
if (theErr == noErr)
{
gTheESAddressTable->theTable[i] = (ProcPtr) theVblPtr;
gTheParamBlock.theCodeResources[i].theAddress = (Ptr) theVblPtr;
}
// Return any errors
return(theErr);
}
//=============================================================================
// InstallLowMemFilter : Install a low-memory filter.
//-----------------------------------------------------------------------------
OSErr InstallLowMemFilter(short i, Ptr theCode)
{ ProcPtr theEntryPoint;
// Get the address of the filter chain.
theEntryPoint = (ProcPtr) gTheParamBlock.theCodeResources[i].theCodeThing.theLowMemFilter.theEntryPoint;
// Save the address currently at the front of the chain in the address table
// and save ourselves in the param block.
gTheESAddressTable->theTable[i] = (ProcPtr) *((void **) theEntryPoint);
gTheParamBlock.theCodeResources[i].theAddress = theCode;
// Insert ourselves into the front of the chain
*((long *) theEntryPoint) = (long) theCode;
// Return any errors
return(noErr);
}
//=============================================================================
// InstallCodeBlock : Install a block of code.
//-----------------------------------------------------------------------------
OSErr InstallCodeBlock(short i, Ptr theCode)
{
// Set the reserved field to some value
gTheParamBlock.theCodeResources[i].theCodeThing.theCodeBlock.refCon = 0xDEADBEEF;
// Save the address of the code block in the address table and the param block
gTheESAddressTable->theTable[i] = (ProcPtr) theCode;
gTheParamBlock.theCodeResources[i].theAddress = theCode;
// Return any errors
return(noErr);
}
//=============================================================================
// InstallTimeManagerTask : Install a Time Manager task.
//-----------------------------------------------------------------------------
OSErr InstallTimeManagerTask(short i, Ptr theCode)
{ TMTask *theTaskPtr;
// Allocate a little block of memory in the System Heap for the task information
theTaskPtr = (TMTask*) NewPtrSys(sizeof(TMTask));
// Fill in the fields, and install it as an Time Manager task. We don't install
// it as with InsXTime because we probably won't need that accurate timing.
theTaskPtr->tmAddr = (TimerUPP) theCode;
theTaskPtr->tmCount = 0;
InsTime((QElemPtr) theTaskPtr);
PrimeTime((QElemPtr) theTaskPtr,
gTheParamBlock.theCodeResources[i].theCodeThing.theTimeManagerTask.theDelay);
// Save the address of the TMTask structure in the address table and the param block
gTheESAddressTable->theTable[i] = (ProcPtr) theTaskPtr;
gTheParamBlock.theCodeResources[i].theAddress = (Ptr) theTaskPtr;
// Return any errors
return(noErr);
}